package cn.buk.api.shdl.service;

import cn.buk.api.shdl.dto.FlightShoppingDto;
import cn.buk.api.shdl.request.IntlFlightShoppingRequest;
import cn.buk.api.shdl.request.UserTokenRequest;
import cn.buk.api.shdl.response.IntlFlightShoppingResponse;
import cn.buk.api.shdl.response.UserTokenResponse;
import cn.buk.api.shdl.util.HttpUtil;
import cn.buk.api.shdl.util.ZipUtil;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpStatus;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;

public class ShdlFlightServiceImpl implements ShdlFlightService {

  private static Logger logger = LogManager.getLogger(ShdlFlightServiceImpl.class);

  private final String email;
  private final String password;
  private final String apiKey;
  private final boolean showJson;

  public ShdlFlightServiceImpl(String email, String password, String apiKey, boolean showJson) {
    this.email = email;
    this.password = password;
    this.apiKey = apiKey;
    this.showJson = showJson;
  }

  /**
   * 获取user的访问token
   * @return
   */
  @Override
  public UserTokenResponse getUserToken() {
    //TODO 需要参数化
    final String url = "http://api.twflight.com/api/user";

    UserTokenRequest request = new UserTokenRequest();
    request.setEmail(this.email);
    request.setPassword(this.password);
    request.setApiKey(this.apiKey);

    final String requestStr = JSON.toJSONString(request);
    final String jsonStr = HttpUtil.postUrl(url, requestStr, null);

    return jsonStr == null ? null : JSON.parseObject(jsonStr, UserTokenResponse.class);
  }

  @Override
  public FlightShoppingDto searchFlights(IntlFlightShoppingRequest request, String username, String password) {
    //TODO 需要参数化url
    final String url = "http://180.168.66.62:18091/api/AirFareSearchOneI";

    final String requestStr = JSON.toJSONString(request);

    if (showJson) {
      logger.info("request: " + requestStr);
      System.out.println("request: " + requestStr);
    }

    final Map<String, String> map = HttpUtil.postUrlWithBasicAuth(url, username, password, requestStr);

    if (showJson) {
      logger.info("response: " + map.get("content"));
      System.out.println("response: " + map.get("content"));
    }

    if (Integer.parseInt(map.get("status")) != HttpStatus.SC_OK) {
      FlightShoppingDto dto = new FlightShoppingDto();
      dto.setErrcode(Integer.parseInt(map.get("status")));
      dto.setErrmsg(map.get("content"));

      return dto;
    }

    final String jsonStr = map.get("content");

    IntlFlightShoppingResponse info = JSON.parseObject(jsonStr, IntlFlightShoppingResponse.class);
    if (info.getData() == null) {
      FlightShoppingDto dto = new FlightShoppingDto();
      dto.setErrcode(10000);
      dto.setErrmsg(info.getMessage());

      return dto;
    }

    String warning = null;
    ObjectMapper objectMapper = new ObjectMapper();
    try {
      FlightShoppingDto rs = objectMapper.readValue(ZipUtil.gunzip(info.getData()), FlightShoppingDto.class);
      return rs;
    } catch (JsonProcessingException e) {
      final String filename = "searchone_" + System.currentTimeMillis() + ".json";
      FileWriter writer;
      try {
        File file = new File(filename);
        writer = new FileWriter(file);
        writer.write("");
        writer.write(ZipUtil.gunzip(info.getData()));
        writer.flush();
        writer.close();

        logger.info(file.getCanonicalPath());
      } catch (IOException ex) {
        logger.error(ex.getMessage());
      }
      logger.error(e.getMessage());


      //TODO 发消息通知
      warning = e.getMessage();
    }

    // 忽略未知字段
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    FlightShoppingDto rs = null;
    try {
      rs = objectMapper.readValue(ZipUtil.gunzip(info.getData()), FlightShoppingDto.class);
    } catch (JsonProcessingException e) {
      logger.error(e.getMessage());
    }

    if (rs != null && warning != null) {
      rs.setWarning(warning);
    }

    return rs;
  }
}
